#include "lib/lock.h"
#include "lib/print.h"
#include "proc/cpu.h"
#include "riscv.h"

// 带层数叠加的关中断
void push_off(void)
{int old = intr_get();
// intr_get() 函数的目的是检查当前的中断使能状态。它通过读取 sstatus 寄存器来确定中断是否被允许。

  intr_off();
//   intr_off() 函数的目的是禁用中断。
//   它通过修改 sstatus 寄存器的特定位来实现这一点。在 RISC-V 架构中，sstatus 寄存器的不同位控制不同的处理器状态，包括中断使能与否。
  if(mycpu1()->noff == 0)
    mycpu1()->origin = old;
  mycpu1()->noff += 1;

}

// 带层数叠加的开中断
void pop_off(void)
{
  cpu_t *c = mycpu1();
  if(intr_get())
    panic("pop_off - interruptible");
  if(c->noff < 1)
    panic("pop_off");
  c->noff -= 1;
  if(c->noff == 0 && c->origin)
    intr_on();

}

// 是否持有自旋锁
// 中断应当是关闭的
bool spinlock_holding(spinlock_t *lk)
{
    int r;
    r = (lk->locked && lk->cpuid == mycpuid());
    return r;
}

// 自选锁初始化
void spinlock_init(spinlock_t *lk, char *name)
{
    lk->name = name;
  lk->locked = 0;
  lk->cpuid = -1;

}

// 获取自选锁
void spinlock_acquire(spinlock_t *lk)
{    
  push_off();
  if(spinlock_holding(lk)){
      printf("lock %s acquire!",lk->name);
      panic("acquire");
  }


  
  while(__sync_lock_test_and_set(&lk->locked, 1) != 0)
    ;


  __sync_synchronize();

  lk->cpuid = mycpuid();

} 

// 释放自旋锁
void spinlock_release(spinlock_t *lk)
{
  if(!spinlock_holding(lk))
    panic("release");

  lk->cpuid= -1;

 
  __sync_synchronize();


  __sync_lock_release(&lk->locked);

  pop_off();

}